package cn.yunbamboos.mybatis.mapping.methods;

import cn.hutool.core.util.StrUtil;
import cn.yunbamboos.mybatis.Constants;
import cn.yunbamboos.mybatis.metadata.TableInfo;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.Configuration;

import java.util.ArrayList;
import java.util.List;

/**
 * 基础的方法构建
 * */
public abstract class BaseMethod implements Constants {

    protected final String methodName;
    protected final Configuration configuration;
    protected final TableInfo tableInfo;
    protected final SqlCommandType sqlCommandType;
    public BaseMethod(String methodName, Configuration configuration, TableInfo tableInfo, SqlCommandType sqlCommandType) {
        this.methodName = methodName;
        this.configuration = configuration;
        this.tableInfo = tableInfo;
        this.sqlCommandType = sqlCommandType;
    }

    public void exec() {
        MappedStatement statement = getMappedStatementBuilder().build();
        configuration.addMappedStatement(statement);
    }

    protected List<ResultMap> getStatementResultMaps(String resultMap) {
        List<ResultMap> resultMaps = new ArrayList<>();
        if (StrUtil.isNotBlank(resultMap)) {
            resultMaps.add(configuration.getResultMap(resultMap));
        }
        return resultMaps;
    }

    protected ParameterMap getStatementParameterMap(String parameterMap) {
        return configuration.getParameterMap(parameterMap);
    }

    protected MappedStatement.Builder getMappedStatementBuilder() {
        Class<?> mapperType = tableInfo.getMapperType();
        String id = mapperType.getName() + DOT + methodName;
        SqlSource sqlSource = getSqlSource();
        return new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
    }

    protected abstract SqlSource getSqlSource();


    /**
     * 构建查询所有SQL方法
     * select {} from {}
     * */
    protected String SELECT_ALL(List<String> columns, String tableName) {
        return StrUtil.format(SELECT_ALL_MODEL, StrUtil.join(", ", columns), tableName);
    }

    /**
     * 构建有条件查询SQL方法
     * select {} from {} where {}
     * */
    protected String SELET_WHERE(List<String> columns, String tableName, List<String> wheres) {
        return StrUtil.format(SELECT_WHERE_MODEL, StrUtil.join(", ", columns), tableName, StrUtil.join("and ", wheres));
    }

    /**
     * 插入数据
     * insert into {} ({}) values ({})
     * */
    protected String INSERT(String tableName, List<String> columns, List<String> values) {
        return StrUtil.format(INSERT_MODEL, tableName, StrUtil.join(", ", columns), StrUtil.join(", ", values));
    }

    /**
     * 更新数据
     * update {} set {} WHERE {}
     * */
    protected String UPDATE(String tableName, List<String> sets, List<String> wheres) {
        return StrUtil.format(UPDATE_MODEL, tableName, StrUtil.join(", ", sets), StrUtil.join("and ", wheres));
    }

    /**
     * 删除数据
     * delete from {} where {}
     * */
    protected String DELETE(String tableName, List<String> wheres) {
        return StrUtil.format(DELETE_MODEL, tableName, StrUtil.join("and ", wheres));
    }

}
